가장 먼저 만들어진 형식. require
, exports
, module.exports
등 NodeJS만들어 졌을 때 있던 것.
Synchronous하게 만들어져 브라우저에서 쓰기 어렵고 브라우저가 바로 이해할 수 없는 형식임.
// utils.js
// we create a function
function add(r) {
return r + r
}
// export (expose) add to other modules
exports.add = add
// index.js
var utils = require("./utils.js")
utils.add(4) // = 8
CJS 팀에서 원하는 방향이 달라 갈라져나온 형식. 비동기 모듈 로딩을 지원한다. RequireJS에서 사용하는 모듈 시스템이고 브라우저에서도 작동한다.
// add.js
define(function() {
return add = function(r) {
return r + r;
}
});
// index.js
define(function(require) {
require('./add');
add(4); // = 8
}
단, 웹사이트가 RequireJS를 지원해야 작동함.
CJS와 AMD가 서로 다른 스펙을 지원하게 되면서 어디든 사용할 수 있는 모듈 시스템이 필요해졌다. AMD기반이지만 CJS와의 호환된다. 그러나 호환성을 지원하다보니 작성하기가 어려워졌다.
위 3개의 형식은 읽기가 어렵고, 정적 코드 분석도 어렵다. ESM은 ECMA팀이 ECMAScript2015(ES6) 표준을 만들 때 포함한 형식이다. 사용하기 쉽고 동기/비동기 모듈 로딩을 모두 지원한다.
// add.js
export function add(r) {
return r + r
}
// index.js
import add from "./add"
add(4) // = 8
정적 분석이 가능하기 때문에 번들러에서 tree-shaking이 가능하다는 장점도 가지고 있다.
단점은 동적 모듈 로딩이 불가능하다.
모든 브라우저에서의 작동을 보장하진 않는다.
(2021.07.10 추가) 이제 대부분의 브라우저가 import
, export
module와 같은 모듈 구문을 지원한다.
<script type="module">
를 이용하여 최상위 모듈을 구성할 수 있다.